package com.hao.tool.web.util;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;

import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * description
 *
 * @author RuiHaoZ on BeiJing
 * @date 2019/6/26 10:22
 */
public class FileUtils {


    /**
     * 判断文件是否存在
     *
     * @param filePath 文件路径
     * @return false or true
     */
    public static boolean isExists(String filePath) {
        File file = new File(filePath);
        return file.exists();
    }

    /**
     * 判断是否是文件夹
     *
     * @param path 文件夹路径
     * @return false or true
     */
    public static boolean isDir(String path) {
        File file = new File(path);
        if (file.exists()) {
            return file.isDirectory();
        } else {
            return false;
        }
    }

    /**
     * 文件或者目录重命名
     *
     * @param oldFilePath 旧文件路径
     * @param newName     新的文件名,可以是单个文件名和绝对路径
     * @return
     */
    public static boolean renameTo(String oldFilePath, String newName) {
        try {
            File oldFile = new File(oldFilePath);
            //若文件存在
            if (oldFile.exists()) {
                //判断是全路径还是文件名
                if (newName.indexOf("/") < 0 && newName.indexOf("\\") < 0) {
                    //单文件名，判断是windows还是Linux系统
                    String absolutePath = oldFile.getAbsolutePath();
                    if (newName.indexOf("/") > 0) {
                        //Linux系统
                        newName = absolutePath.substring(0, absolutePath.lastIndexOf("/") + 1) + newName;
                    } else {
                        newName = absolutePath.substring(0, absolutePath.lastIndexOf("\\") + 1) + newName;
                    }
                }
                File file = new File(newName);
                //判断重命名后的文件是否存在
                if (file.exists()) {
                    System.out.println("该文件已存在,不能重命名");
                } else {
                    //不存在，重命名
                    return oldFile.renameTo(file);
                }
            } else {
                System.out.println("原该文件不存在,不能重命名");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * 文件拷贝操作
     *
     * @param sourceFile 源文件路径
     * @param targetFile 目标文件路径
     */
    public static void copy(String sourceFile, String targetFile) {
        File source = new File(sourceFile);
        File target = new File(targetFile);
        target.getParentFile().mkdirs();
        FileInputStream fis = null;
        FileOutputStream fos = null;
        FileChannel in = null;
        FileChannel out = null;
        try {
            fis = new FileInputStream(source);
            fos = new FileOutputStream(target);
            //得到对应的文件通道
            in = fis.getChannel();
            //得到对应的文件通道
            out = fos.getChannel();
            //连接两个通道，并且从in通道读取，然后写入out通道
            in.transferTo(0, in.size(), out);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
                if (fos != null) {
                    fos.close();
                }
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取某个文件夹下的所有文件
     *
     * @param fileNameList 存放文件名称的list
     * @param path         文件夹的路径
     */
    public static void getAllFileName(String path, ArrayList<String> fileNameList) {
        boolean flag = false;
        File file = new File(path);
        File[] tempList = file.listFiles();

        assert tempList != null;
        for (File value : tempList) {
            if (value.isFile()) {
                fileNameList.add(value.getName());
            }
            if (value.isDirectory()) {
                getAllFileName(value.getAbsolutePath(), fileNameList);
            }
        }
    }

    /**
     * 删除文件
     *
     * @param fileName 文件名 字符串
     * @return
     */
    public static boolean delete(String fileName) {
        try {
            File sourceFile = new File(fileName);
            if (sourceFile.isDirectory()) {
                for (File listFile : Objects.requireNonNull(sourceFile.listFiles())) {
                    delete(listFile.getAbsolutePath());
                }
            }
            return sourceFile.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 删除文件
     *
     * @param f
     * @return
     */
    public static boolean recurDelete(File f) {
        try {
            if (f.isFile()) {
                f.delete();
                return true;
            }
            for (File fi : f.listFiles()) {
                if (fi.isDirectory()) {
                    recurDelete(fi);
                } else {
                    fi.delete();
                }
            }
            f.delete();
        } catch (NullPointerException n) {
            System.out.println("Sorry,No such file");
            return false;
        }
        return true;
    }


    /**
     * 按文件修改日期：递增
     *
     * @param filePath 文件夹的路径
     */
    public static void orderByDate(String filePath, ArrayList<String> fileNameList) {
        File file = new File(filePath);
        File[] files = file.listFiles();
        assert files != null;
        Arrays.sort(files, new Comparator<File>() {
            @Override
            public int compare(File f1, File f2) {
                long diff = f1.lastModified() - f2.lastModified();
                if (diff > 0) {
                    return 1;
                } else if (diff == 0) {
                    return 0;
                } else {
                    //如果 if 中修改为 返回-1 同时此处修改为返回 1  排序就会是递减
                    return -1;
                }
            }

            @Override
            public boolean equals(Object obj) {
                return true;
            }
        });
        for (File value : files) {
            fileNameList.add(value.getName());
        }

    }

    public static String resourceLoader(String fileFullPath) {
        ClassPathResource cpr = new ClassPathResource(fileFullPath);
        try {
            byte[] bytes = FileCopyUtils.copyToByteArray(cpr.getInputStream());
            String date = new String(bytes, StandardCharsets.UTF_8);
            return date;
        } catch (Exception e) {
            return null;
        }
    }

    public static String readToString(File file) {
        String encoding = "UTF-8";

        if (!file.exists() || !file.isFile()) {
            return null;
        }
        Long fileLength = file.length();
        byte[] fileContent = new byte[fileLength.intValue()];
        try {
            FileInputStream in = new FileInputStream(file);
            in.read(fileContent);
            in.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            return new String(fileContent, encoding);
        } catch (UnsupportedEncodingException e) {
            System.err.println("The OS does not support " + encoding);
            e.printStackTrace();
            return null;
        }
    }

    public static String readToString(String fileName) {
        File file = new File(fileName);
        return readToString(file);
    }

    /**
     * 字符串转文件
     *
     * @param content
     * @param file
     * @throws IOException
     */
    public static File stringToFile(String content, File file) throws IOException {
        if (content == null || "".equals(content)) {
            return null;
        }
        byte[] buff = Base64.getDecoder().decode(content);
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(file);
            outputStream.write(buff);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return file;
    }


    /**
     * 文件转字符串
     *
     * @param file
     * @return
     */
    public static String file2Base64(File file) {
        if (file == null) {
            return null;
        }
        String base64 = null;
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(file);
            byte[] buff = new byte[fin.available()];
            fin.read(buff);
            base64 = Base64.getEncoder().encodeToString(buff);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fin != null) {
                try {
                    fin.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return base64;
    }

    /**
     * 递归删除目录中的子目录下
     *
     * @param dir
     */
    public static void deleteDir(File dir) {

        if (dir.isDirectory()) {
            String[] children = dir.list();
            for (int i = 0; i < children.length; i++) {
                deleteDir(new File(dir, children[i]));
            }
        }
        dir.delete(); //目录此时为空，可以删除
    }

    /**
     * 网络图片转化为 base64格式
     *
     * @param imgUrl 网络图片地址
     * @return base64格式的图片信息
     * @throws IOException
     */
    public static String netImageToBase64(
            String imgUrl) {
        if (StringUtils.isNotBlank(imgUrl)) {
            try {
                URI uri = null;
                try {
                    uri = new URI(imgUrl);
                } catch (URISyntaxException e) {
                    e.printStackTrace();
                    return null;
                }
                byte[] bytes = IOUtils.toByteArray(uri);
                return Base64.getEncoder().encodeToString(bytes);
            } catch (IOException e) {
                return null;
            }
        }
        return null;

    }

    public static void main(String[] args) throws IOException {
//        System.out.println(FileUtil.class.getResource("/communication/errImgList.json").toExternalForm());
        String fileUrl = System.getProperty("user.dir") + "/src/test/resources/communication/";
        readToString("User/dd.st");
        System.out.println(fileUrl);
    } // 第五种：  获取所有的类路径 包括jar包的路径

}
